﻿using DevComponents.DotNetBar.Controls;
using DevComponents.DotNetBar.Metro;
using DevComponents.Editors;
using DevComponents.Editors.DateTimeAdv;
using DonFileteSIC.Controlador;
using DonFileteSIC.Modelo.Reportes;
using DonFileteSIC.Vista;
using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;

namespace DonFileteSIC
{
    public partial class Main : MetroAppForm
    {
        private ClasesDBDataContext db = new ClasesDBDataContext();
        private SicPeriodo periodoContable = null;
        private CapitalReinvertir porcentajeCapital = new CapitalReinvertir();

        public Main()
        {
            InitializeComponent();
        }

        #region Login

        private void validarTipoUsuario(Int32 IdTipoUsuario)
        {
            var collection = this.db.SicAccesoUsuario.Where(a => a.SicTipoUsuario_Id_Tipo_Usuario == IdTipoUsuario).ToList();
            var modulos = this.todosModulos();
            foreach (var item in modulos)
            {
                Type mod = item.Mod.GetType();

                if (collection.Count > 0)
                {
                    if (mod.FullName.Equals("DevComponents.DotNetBar.ButtonItem"))
                    {
                        DevComponents.DotNetBar.ButtonItem modulo = (DevComponents.DotNetBar.ButtonItem)item.Mod;
                        modulo.Enabled = collection.Exists(i => i.SicModulo_Id_Modulo == item.IdModulo);
                    }
                    else
                    {
                        DevComponents.DotNetBar.Metro.MetroTileItem modulo = (DevComponents.DotNetBar.Metro.MetroTileItem)item.Mod;
                        modulo.Enabled = collection.Exists(i => i.SicModulo_Id_Modulo == item.IdModulo);
                    }
                }
            }
            this.menuPrincipal.Visible = true;
            this.ocultarPanelesExcepto(this.panelHome);
        }

        private void btnLogin_Click(object sender, EventArgs e)
        {
            var usuario = this.db.SicUsuario.SingleOrDefault(u => u.Nombre_Usuario == this.txtNombreUsuarioLogin.Text && u.Contraseña == this.txtContraseñaLogin.Text);
            if (usuario != null)
            {
                this.labelNombreUsuarioHome.Text = usuario.Nick_Usuario;
                this.labelTipoUsuarioHome.Text = usuario.SicTipoUsuario.Nombre_Tipo_Usuario;
                this.validarTipoUsuario(usuario.SicTipoUsuario.Id_Tipo_Usuario);
                
                this.labelErrorLogin.Visible = false;
            }
            else
                this.labelErrorLogin.Visible = true;
            this.txtNombreUsuarioLogin.Text = "";
            this.txtContraseñaLogin.Text = "";
        }

        private void btnInvitado_Click(object sender, EventArgs e)
        {
            this.validarTipoUsuario(3);//3 es Invitado
        }

        #endregion

        #region Métodos Main

        private void Main_Load(object sender, EventArgs e)
        {
            this.subproceso.RunWorkerAsync();
        }

        private void subproceso_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            this.labelFechaInicioPeriodoContableHome.Invoke((MethodInvoker)
                delegate
                {
                    this.labelErrorLogin.ForeColor = Color.Red;
                    this.cargarComponentes();
                });
        }

        private void subproceso_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            this.progreso.Visible = false;
            this.panelLogin.Visible = true;
            this.ocultarPanelesExcepto(this.panelLogin);
        }

        private void cargarComponentes()
        {
            this.comprobarPeriodoContable();
            this.cmbMesPlanilla.DataSource = this.obtenerMeses();
            this.cmbMesPlanilla.DisplayMember = "nombreMes";
            this.cmbMesPlanilla.ValueMember = "numeroMes";
            
            this.reportBalanceComprobacion.RefreshReport();
        }

        private void btnMinimizarMain_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
        }

        private void btnCerrarMain_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnHelp_Click(object sender, EventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start(@"help\Manual de Usuario Don Filete SIC.pdf");
            }
            catch (Win32Exception ex)
            {
                mensajeError(ex);
            }
        }

        #endregion

        #region Métodos en General

        private List<Modulo> todosModulos()
        {
            List<Modulo> modulos = new List<Modulo>();

            //Botones Menú
            modulos.Add(new Modulo() { IdModulo = 1, Mod = this.btnCatalogoCuentas });
            modulos.Add(new Modulo() { IdModulo = 2, Mod = this.btnCompras });
            modulos.Add(new Modulo() { IdModulo = 3, Mod = this.btnVentas });
            modulos.Add(new Modulo() { IdModulo = 4, Mod = this.btnOtrasTransacciones });
            modulos.Add(new Modulo() { IdModulo = 5, Mod = this.btnRequisiciones });
            modulos.Add(new Modulo() { IdModulo = 6, Mod = this.btnCatalogoDeProductos });
            modulos.Add(new Modulo() { IdModulo = 7, Mod = this.btnIniciarPeriodoContable });
            modulos.Add(new Modulo() { IdModulo = 8, Mod = this.btnCerrarPeriodoContable });
            modulos.Add(new Modulo() { IdModulo = 9, Mod = this.btnPlanilla });
            modulos.Add(new Modulo() { IdModulo = 10, Mod = this.btnGenerarPlanilla });
            modulos.Add(new Modulo() { IdModulo = 11, Mod = this.btnGestionarEmpleados });
            modulos.Add(new Modulo() { IdModulo = 12, Mod = this.btnGestionarPuestosYSalarios });
            modulos.Add(new Modulo() { IdModulo = 13, Mod = this.btnGestionarUsuarios });
            modulos.Add(new Modulo() { IdModulo = 15, Mod = this.btnBalanceComprobacion });
            modulos.Add(new Modulo() { IdModulo = 16, Mod = this.btnEstadoResultado });
            modulos.Add(new Modulo() { IdModulo = 17, Mod = this.btnEstadoCapital });
            modulos.Add(new Modulo() { IdModulo = 18, Mod = this.btnBalanceGeneral });

            //Metro Tiles
            modulos.Add(new Modulo() { IdModulo = 1, Mod = this.metroCatalogoCuentas });
            modulos.Add(new Modulo() { IdModulo = 4, Mod = this.metroOtrasTransacciones });
            modulos.Add(new Modulo() { IdModulo = 2, Mod = this.metroCompras });
            modulos.Add(new Modulo() { IdModulo = 3, Mod = this.metroVentas });
            modulos.Add(new Modulo() { IdModulo = 15, Mod = this.metroEstadosFinancieros });
            modulos.Add(new Modulo() { IdModulo = 5, Mod = this.metroRequisiciones });
            modulos.Add(new Modulo() { IdModulo = 10, Mod = this.metroGenerarPlanilla });
            modulos.Add(new Modulo() { IdModulo = 11, Mod = this.metroGestionEmpleados });
            modulos.Add(new Modulo() { IdModulo = 6, Mod = this.metroGestionProducto });
            modulos.Add(new Modulo() { IdModulo = 9, Mod = this.metroConsultarPlanilla });

            return modulos;
        }

        private void autoSumarCuentasSuperiores()
        {
            Decimal saldoDeudorM = 0.0M, saldoAcreedorM = 0.0M;
            Decimal saldoDeudorP = 0.0M, saldoAcreedorP = 0.0M;
            List<SicCuenta> cuentas = this.db.ObtenerCuentasMayores();
            foreach (SicCuenta cuenta in cuentas)
            {
                List<SicCuenta> cuentasP = this.db.ObtenerCuentas(cuenta.Id_Cuenta.ToString());
                foreach (SicCuenta cuentaP in cuentasP)
                {
                    
                    List<SicCuenta> cuentasS = this.db.ObtenerCuentas(cuentaP.Id_Cuenta.ToString());
                    foreach (SicCuenta cuentaS in cuentasS)
                    {
                        saldoAcreedorP += cuentaS.Saldo_Acreedor;
                        saldoDeudorP += cuentaS.Saldo_Deudor;
                    }
                    if (cuentasS.Count > 0)
                    {
                        cuentaP.Saldo_Acreedor = saldoAcreedorP;
                        cuentaP.Saldo_Deudor = saldoDeudorP;
                    }
                    saldoAcreedorM += cuentaP.Saldo_Acreedor;
                    saldoDeudorM += cuentaP.Saldo_Deudor;
                    saldoAcreedorP = 0.0M;
                    saldoDeudorP = 0.0M;
                    
                    this.db.ActualizarSaldos(cuentaP.Saldo_Deudor, cuentaP.Saldo_Acreedor, cuentaP.Id_Cuenta);
                }
                if (cuentasP.Count > 0)
                {
                    cuenta.Saldo_Acreedor = saldoAcreedorM;
                    cuenta.Saldo_Deudor = saldoDeudorM;
                }
                saldoAcreedorM = 0.0M;
                saldoDeudorM = 0.0M;
                this.db.ActualizarSaldos(cuenta.Saldo_Deudor, cuenta.Saldo_Acreedor, cuenta.Id_Cuenta);
            }
        }

        private void btnHome_Click(object sender, EventArgs e)
        {
            this.ocultarPanelesExcepto(this.panelHome);
        }

        private void comprobarPeriodoContable()
        {
            this.periodoContable = this.db.ObtenerPeriodoContable();
            if (this.periodoContable != null)
            {
                //Si ya fue cerrado el periodo contable
                if (this.periodoContable.Estado == 0)
                {
                    this.btnCerrarPeriodoContable.Enabled = false;
                    this.btnIniciarPeriodoContable.Enabled = true;
                    this.labelFechaInicioPeriodoContableHome.Text = this.periodoContable.Fecha_Inicio.Value.ToShortDateString();
                    this.labelFechaFinPeriodoContableHome.Text = this.periodoContable.Fecha_Fin.Value.ToShortDateString();
                }
                else
                {
                    this.labelFechaInicioPeriodoContableHome.Text = this.periodoContable.Fecha_Inicio.Value.ToShortDateString();
                    this.labelFechaFinPeriodoContableHome.Text = "Sin Definir";
                    this.btnCerrarPeriodoContable.Enabled = true;
                    this.btnIniciarPeriodoContable.Enabled = false;
                }
            }
            else
            {
                this.labelFechaFinPeriodoContableHome.Text = "Sin Definir";
                this.labelFechaInicioPeriodoContableHome.Text = "Sin Definir";
                this.btnCerrarPeriodoContable.Enabled = false;
                this.btnIniciarPeriodoContable.Enabled = true;
            }
        }

        private bool controlesNullos(params Boolean[] controles)
        {
            foreach (Boolean item in controles)
            {
                if (item)
                {
                    MessageBox.Show("Hay un campo vacío.\nRevise por favor.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return true;
                }
            }
            return false;
        }

        private List<Mes> obtenerMeses()
        {
            List<Mes> meses = new List<Mes>();

            meses.Add(new Mes() { numeroMes = 1, nombreMes = "Enero" });
            meses.Add(new Mes() { numeroMes = 2, nombreMes = "Febrero" });
            meses.Add(new Mes() { numeroMes = 3, nombreMes = "Marzo" });
            meses.Add(new Mes() { numeroMes = 4, nombreMes = "Abril" });
            meses.Add(new Mes() { numeroMes = 5, nombreMes = "Mayo" });
            meses.Add(new Mes() { numeroMes = 6, nombreMes = "Junio" });
            meses.Add(new Mes() { numeroMes = 7, nombreMes = "Julio" });
            meses.Add(new Mes() { numeroMes = 8, nombreMes = "Agosto" });
            meses.Add(new Mes() { numeroMes = 9, nombreMes = "Septiembre" });
            meses.Add(new Mes() { numeroMes = 10, nombreMes = "Octubre" });
            meses.Add(new Mes() { numeroMes = 11, nombreMes = "Noviembre" });
            meses.Add(new Mes() { numeroMes = 12, nombreMes = "Diciembre" });

            return meses;
        }

        public static void mensajeError(Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message + "\n\nPila de llamadas: " + ex.StackTrace, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void ocultarPanelesExcepto(params SlidePanel[] paneles)
        {
            this.panelLogin.IsOpen = this.panelExcepcion(this.panelLogin, paneles);
            this.panelHome.IsOpen = this.panelExcepcion(this.panelHome, paneles);

            this.panelCatalogoCuentas.IsOpen = this.panelExcepcion(this.panelCatalogoCuentas, paneles);
            this.panelLateralCuentas.IsOpen = this.panelExcepcion(this.panelLateralCuentas, paneles);
            this.panelOtrasTransacciones.IsOpen = this.panelExcepcion(this.panelOtrasTransacciones, paneles);
            this.panelLateralTransacciones.IsOpen = this.panelExcepcion(this.panelLateralTransacciones, paneles);
            this.panelBalanceComprobacion.IsOpen = this.panelExcepcion(this.panelBalanceComprobacion, paneles);
            this.panelIniciarPeriodoContable.IsOpen = this.panelExcepcion(this.panelIniciarPeriodoContable, paneles);
            this.panelCerrarPeriodoContable.IsOpen = this.panelExcepcion(this.panelCerrarPeriodoContable, paneles);
            this.panelEstadoResultado.IsOpen = this.panelExcepcion(this.panelEstadoResultado, paneles);
            this.panelCatalogoDeProductos.IsOpen = this.panelExcepcion(this.panelCatalogoDeProductos, paneles);
            this.panelModificarProducto.IsOpen = this.panelExcepcion(this.panelModificarProducto, paneles);
            this.panelEmpleados.IsOpen = this.panelExcepcion(this.panelEmpleados, paneles);
            this.panelLateralEmpleados.IsOpen = this.panelExcepcion(this.panelLateralEmpleados, paneles);
            this.panelPlanilla.IsOpen = this.panelExcepcion(this.panelPlanilla, paneles);
            this.panelLateralPuesto.IsOpen = this.panelExcepcion(this.panelLateralPuesto, paneles);
            this.panelPuestos.IsOpen = this.panelExcepcion(this.panelPuestos, paneles);
            this.panelEstadoCapital.IsOpen = this.panelExcepcion(this.panelEstadoCapital, paneles);
            this.panelBalanceGeneral.IsOpen = this.panelExcepcion(this.panelBalanceGeneral, paneles);
            this.panelGenerarPlanilla.IsOpen = this.panelExcepcion(this.panelGenerarPlanilla, paneles);
            this.panelCompras.IsOpen = this.panelExcepcion(this.panelCompras, paneles);
            this.panelRequisiciones.IsOpen = this.panelExcepcion(this.panelRequisiciones, paneles);
            this.panelVentas.IsOpen = this.panelExcepcion(this.panelVentas, paneles);
            this.panelNuevoUsuario.IsOpen = this.panelExcepcion(this.panelNuevoUsuario, paneles);
            this.panelLateralModificarUsuario.IsOpen = this.panelExcepcion(this.panelLateralModificarUsuario, paneles);
        }

        private bool panelExcepcion(SlidePanel panelAEvaluar, SlidePanel[] paneles)
        {
            foreach (SlidePanel panel in paneles)
            {
                if (panelAEvaluar == panel)
                    return true;
            }
            return false;
        }

        //Retorna 0 si no hay nada, 1 si se ha iniciado un periodo y 2 si ya se cerró.
        private int periodoContableIniciado()
        {
            if (this.periodoContable == null)
                return 0;
            if (this.periodoContable.Estado == 1)
                return 1;
            return 2;
        }

        #endregion

        #region Menú Principal

        private void btnCatalogoCuentas_Click(object sender, EventArgs e)
        {
            this.llenarArbol();
            this.treeCatalogo.Nodes[0].EnsureVisible();
            this.txtAgregarNombreClase.Text = "";
            this.txtNombreAgregarCuenta.Text = "";
            this.ocultarPanelesExcepto(this.panelCatalogoCuentas);
        }

        private void btnBalanceComprobacion_Click(object sender, EventArgs e)
        {
            if (this.periodoContableIniciado() == 0)
            {
                MessageBox.Show("No hay ningún Período Contable en el sistema.",
                    "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (this.periodoContableIniciado() == 2)
            {
                this.txtFechaInicioBC.ValueObject = this.periodoContable.Fecha_Inicio.Value;
                this.txtFechaFinBC.ValueObject = this.periodoContable.Fecha_Fin.Value;
                this.ocultarPanelesExcepto(this.panelBalanceComprobacion);
                this.generarBalanceComprobacion(this.periodoContable.Fecha_Inicio.Value, this.periodoContable.Fecha_Fin.Value);

                this.reportBalanceComprobacion.RefreshReport();
            }
            else
                MessageBox.Show("El Período Contable Actual aún no se ha cerrado.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void btnEstadoResultado_Click(object sender, EventArgs e)
        {
            if (this.periodoContableIniciado() == 0)
            {
                MessageBox.Show("No hay ningún Período Contable en el sistema.",
                    "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (this.periodoContableIniciado() == 2)
            {
                this.txtFechaInicioER.ValueObject = this.periodoContable.Fecha_Inicio.Value;
                this.txtFechaFinER.ValueObject = this.periodoContable.Fecha_Fin.Value;
                this.generarEstadoResultado(this.periodoContable.Fecha_Inicio.Value, this.periodoContable.Fecha_Fin.Value);
                this.ocultarPanelesExcepto(this.panelEstadoResultado);
                this.reportEstadoResultado.RefreshReport();
            }
            else
                MessageBox.Show("El Período Contable Actual aún no se ha cerrado.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void btnEstadoCapital_Click(object sender, EventArgs e)
        {
            if (this.periodoContableIniciado() == 0)
            {
                MessageBox.Show("No hay ningún Período Contable en el sistema.",
                    "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (this.periodoContableIniciado() == 2)
            {
                this.txtFechaInicioEC.ValueObject = this.periodoContable.Fecha_Inicio.Value;
                this.txtFechaFinEC.ValueObject = this.periodoContable.Fecha_Fin.Value;
                this.generarEstadoCapital(this.periodoContable.Fecha_Inicio.Value, this.periodoContable.Fecha_Fin.Value, this.periodoContable.Porcentaje_Capital);
                this.ocultarPanelesExcepto(this.panelEstadoCapital);
                this.reportEstadoCapital.RefreshReport();
            }
            else
                MessageBox.Show("El Período Contable Actual aún no se ha cerrado.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void btnBalanceGeneral_Click(object sender, EventArgs e)
        {
            if (this.periodoContableIniciado() == 0)
            {
                MessageBox.Show("No hay ningún Período Contable en el sistema.",
                    "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (this.periodoContableIniciado() == 2)
            {
                this.txtFechaInicioBG.ValueObject = this.periodoContable.Fecha_Inicio.Value;
                this.txtFechaFinBG.ValueObject = this.periodoContable.Fecha_Fin.Value;
                this.generarBalanceGeneral(this.periodoContable.Fecha_Inicio.Value, this.periodoContable.Fecha_Fin.Value);
                this.ocultarPanelesExcepto(this.panelBalanceGeneral);
                this.reportBalanceGeneral.RefreshReport();
            }
            else
                MessageBox.Show("El Período Contable Actual aún no se ha cerrado.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            
        }

        private void btnOtrasTransacciones_Click(object sender, EventArgs e)
        {
            if (this.periodoContableIniciado() == 0)
            {
                MessageBox.Show("No hay ningún Período Contable en el sistema.",
                    "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (this.periodoContableIniciado() == 2)
            {
                MessageBox.Show("Las transacciones que se realicen serán de Ajuste.",
                    "Transacciones de Ajuste", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                this.labelTituloOtrasTransacciones.Text = "Nueva Transacción de Ajuste";
            }
            this.txtFechaOtrasTransacciones.ValueObject = null;
            this.txtConceptoOtrasTransacciones.Text = "";
            this.txtImporteOtrasTransacciones.Text = "";
            this.tablaCuentasOtrasTransacciones.Rows.Clear();
            this.txtCodigoCuentaOtrasTransacciones.Text = "";
            this.txtCargoOtrasTransacciones.ValueObject = null;
            this.txtAbonoOtrasTransacciones.ValueObject = null;

            this.txtCodigoCuentaOtrasTransacciones.AutoCompleteCustomSource = this.autoCompleteCuentas();
            this.ocultarPanelesExcepto(this.panelOtrasTransacciones, this.panelLateralTransacciones);
        }

        private void btnCompras_Click(object sender, EventArgs e)
        {
            if (this.periodoContableIniciado() == 0)
            {
                MessageBox.Show("No hay ningún Período Contable en el sistema.",
                    "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (this.periodoContableIniciado() == 2)
            {
                MessageBox.Show("Debe iniciar el período contable para realizar una compra.",
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            this.cmbProductoCompra.DataSource = this.db.SicProducto.Where(p => p.SicTipoProducto_Id_Tipo_Producto == 1).ToList();
            this.cmbProductoCompra.DisplayMember = "Nombre_Producto";
            this.cmbProductoCompra.ValueMember = "Id_Producto";
            this.txtCantidadProductoCompra.ValueObject = null;
            this.txtPrecioCompra.ValueObject = null;
            this.txtFechaCompras.ValueObject = null;
            if (this.cmbProductoCompra.Items.Count > 0)
            this.cmbProductoCompra.SelectedIndex = 0;
            if (this.cmbTipoCompra.Items.Count > 0)
            this.cmbTipoCompra.SelectedIndex = 0;
            this.txtMontoCompras.Text = "";
            this.tablaCompras.Rows.Clear();
            this.ocultarPanelesExcepto(this.panelCompras);
        }

        private void btnVentas_Click(object sender, EventArgs e)
        {
            if (this.periodoContableIniciado() == 0)
            {
                MessageBox.Show("No hay ningún Período Contable en el sistema.",
                    "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (this.periodoContableIniciado() == 2)
            {
                MessageBox.Show("Debe iniciar el período contable para realizar una venta.",
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            this.cmbProductoVentas.DataSource = this.db.SicProducto.Where(p => p.SicTipoProducto_Id_Tipo_Producto == 3).ToList();
            this.cmbProductoVentas.DisplayMember = "Nombre_Producto";
            this.cmbProductoVentas.ValueMember = "Id_Producto";

            this.labelEnExistenciaVentas.Text = this.existenciaProducto((SicProducto)this.cmbProductoVentas.SelectedItem).ToString() + " kg";


            this.txtCantidadVentas.ValueObject = null;
            this.txtPrecioVenta.ValueObject = null;
            this.txtFechaVentas.ValueObject = null;
            if (this.cmbProductoVentas.Items.Count > 0)
            this.cmbProductoVentas.SelectedIndex = 0;
            if (this.cmbTipoVentas.Items.Count > 0)
            this.cmbTipoVentas.SelectedIndex = 0;
            this.txtMontoTotalVentas.Text = "";
            this.tablaVentas.Rows.Clear();
            this.ocultarPanelesExcepto(this.panelVentas);
        }

        private void btnRequisiciones_Click(object sender, EventArgs e)
        {
            if (this.periodoContableIniciado() == 0)
            {
                MessageBox.Show("No hay ningún Período Contable en el sistema.",
                    "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (this.periodoContableIniciado() == 2)
            {
                MessageBox.Show("Debe iniciar el período contable para enviar requisiciones.",
                    "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            this.tablaRequisicion.Rows.Clear();
            this.cmbDepartamentoSolicitanteRequisiciones.DataSource = this.db.SicDepartamento.ToList();
            this.cmbDepartamentoSolicitanteRequisiciones.DisplayMember = "Nombre_Departamento";
            this.cmbDepartamentoSolicitanteRequisiciones.ValueMember = "Id_Departamento";
            int idDepartamento = (Int32)this.cmbDepartamentoSolicitanteRequisiciones.SelectedValue;
            String departamento = (idDepartamento == 1) ? "Depto. Descamado y Eviscerado" : "Depto. Descabezado y Deshuesado";
            this.cmbProductoRequisiciones.DataSource = this.db.SicProducto.Where(p => p.SicTipoProducto_Id_Tipo_Producto == idDepartamento).ToList();
            this.cmbProductoRequisiciones.DisplayMember = "Nombre_Producto";
            this.cmbProductoRequisiciones.ValueMember = "Id_Producto";
            this.labelDepartamentoSolicitanteRequisiciones.Text = departamento;
            //Existencia del producto
            this.labelEnExistenciaRequisiciones.Text = this.existenciaProducto((SicProducto)this.cmbProductoRequisiciones.SelectedItem).ToString() + " kg";

            this.txtCantidadRequisiciones.ValueObject = null;
            this.txtFechaRequisiciones.ValueObject = null;
            
            this.ocultarPanelesExcepto(this.panelRequisiciones);
        }

        private void btnIniciarPeriodoContable_Click(object sender, EventArgs e)
        {
            this.txtFechaInicioPeriodoContable.ValueObject = null;
            this.ocultarPanelesExcepto(this.panelIniciarPeriodoContable);
        }

        private void btnCerrarPeriodoContable_Click(object sender, EventArgs e)
        {
            this.txtFechaCierrePeriodoContable.ValueObject = null;
            this.ocultarPanelesExcepto(this.panelCerrarPeriodoContable);
        }

        private void btnCatalogoDeProductos_Click(object sender, EventArgs e)
        {
            this.comboBoxtipoProducto.DataSource = this.db.SicTipoProducto.ToList();
            this.comboBoxtipoProducto.DisplayMember = "Nombre_Tipo_Producto";
            this.comboBoxtipoProducto.ValueMember = "Id_Tipo_Producto";
            this.comboBoxTipoProductoMOD.DataSource = this.db.SicTipoProducto.ToList();
            this.comboBoxTipoProductoMOD.DisplayMember = "Nombre_Tipo_Producto";
            this.comboBoxTipoProductoMOD.ValueMember = "Id_Tipo_Producto";

            this.textCuentaAsociada.AutoCompleteCustomSource = this.autoCompleteCuentas();
            this.textoCuentaAsociadaMOD.AutoCompleteCustomSource = this.autoCompleteCuentas();

            this.textCuentaAsociada.Text = "";
            this.textoCuentaAsociadaMOD.Text = "";
            this.textoNombreProducto.Text = "";
            this.textoNombreProductoMOD.Text = "";
            this.textoIdentificadorMod.Text = "";

            this.llenarTablaProductos();

            this.ocultarPanelesExcepto(this.panelCatalogoDeProductos, this.panelModificarProducto);
        }

        private void btnGestionarEmpleados_Click(object sender, EventArgs e)
        {
            this.llenarTablaEmpleados();

            var collection = this.db.SicPuesto.ToList();
            var collectionMod = this.db.SicPuesto.ToList();

            this.cmbPuestoEmpleado.DataSource = collection;
            this.cmbPuestoEmpleado.DisplayMember = "Nombre_Puesto";
            this.cmbPuestoEmpleado.ValueMember = "Id_Puesto";

            this.cmbPuestoEmpleadoMod.DataSource = collectionMod;
            this.cmbPuestoEmpleadoMod.DisplayMember = "Nombre_Puesto";
            this.cmbPuestoEmpleadoMod.ValueMember = "Id_Puesto";

            this.txtNombreEmpleado.Text = "";
            this.txtNombreEmpleadoMod.Text = "";
            this.txtFechaContratacionEmpleado.ValueObject = null;
            this.txtFechaContratacionEmpleadoMod.ValueObject = null;

            this.ocultarPanelesExcepto(this.panelEmpleados, this.panelLateralEmpleados);
        }

        private void btnPlanilla_Click(object sender, EventArgs e)
        {
            this.cmbMesPlanilla.SelectedValue = DateTime.Now.Month;
            this.txtAñoPlanilla.Value = DateTime.Now.Year;
            Mes mes = (Mes)this.cmbMesPlanilla.SelectedItem;
            this.consultarPlanilla(DateTime.Now, mes.nombreMes);
        }

        private void btnGestionarPuestosYSalarios_Click(object sender, EventArgs e)
        {
            this.llenarTablaPuestos();
            this.txtNombrePuesto.Text = "";
            this.txtNombrePuestoMod.Text = "";
            this.txtSalarioPuesto.ValueObject = null;
            this.txtSalarioPuestoMod.ValueObject = null;
            this.txtValorHoraExtraPuesto.ValueObject = null;
            this.txtValorHoraExtraPuestoMod.ValueObject = null;
            this.ocultarPanelesExcepto(this.panelPuestos, this.panelLateralPuesto);
        }

        private void btnGenerarPlanilla_Click(object sender, EventArgs e)
        {
            this.llenarTablaGenerarPlanilla();
            this.ocultarPanelesExcepto(this.panelGenerarPlanilla);
        }

        private void btnGestionarUsuarios_Click(object sender, EventArgs e)
        {
            var tiposUsuarios = this.db.SicTipoUsuario.Where(u => u.Id_Tipo_Usuario != 3).ToList();
            this.comboBoxTipoUsuario.DataSource = tiposUsuarios;
            this.comboBoxTipoUsuario.DisplayMember = "Nombre_Tipo_Usuario";
            this.comboBoxTipoUsuario.ValueMember = "Id_Tipo_Usuario";

            var tiposUsuariosMOD = this.db.SicTipoUsuario.Where(u => u.Id_Tipo_Usuario != 3).ToList();
            this.comboTipoUsuarioMOD.DataSource = tiposUsuariosMOD;
            this.comboTipoUsuarioMOD.DisplayMember = "Nombre_Tipo_Usuario";
            this.comboTipoUsuarioMOD.ValueMember = "Id_Tipo_usuario";

            this.textNombreUsuario.Text = "";
            this.textNickUsuario.Text = "";
            this.textContraseña.Text = "";
            this.txtConfirmarContraseñaUsuario.Text = "";
            this.textNombreUsuarioMOD.Text = "";
            this.textNickUsuarioMOD.Text = "";
            this.textUsuarioContraseñaMOD.Text = "";
            this.txtConfirmarContraseñaUsuarioMOD.Text = "";
            this.llenarTablaUsuario();
            this.ocultarPanelesExcepto(this.panelNuevoUsuario, this.panelLateralModificarUsuario);
        }


        #endregion

        //Módulos

        # region Catálogo de Cuentas

        private void llenarArbol()
        {
            this.treeCatalogo.Nodes.Clear();
            List<SicClase> clases = this.db.ObtenerClases();
            foreach (SicClase clase in clases)
            {
                TreeNode nodoClase = new TreeNode(clase.Id_Clase + " - " + clase.Nombre_Clase);
                Nodo nodo0 = new Nodo();
                nodo0.nombre = clase.Nombre_Clase;
                nodo0.codigo = clase.Id_Clase;
                nodo0.id = clase.Id_Clase;
                nodoClase.Tag = nodo0;
                this.treeCatalogo.Nodes.Add(nodoClase);
                List<SicGrupo> grupos = this.db.ObtenerGrupos(clase.Id_Clase);
                foreach (SicGrupo grupo in grupos)
                {
                    TreeNode nodoGrupo = new TreeNode(grupo.Codigo_Grupo + " - " + grupo.Nombre_Grupo);
                    Nodo nodo1 = new Nodo();
                    nodo1.nombre = grupo.Nombre_Grupo;
                    nodo1.codigo = grupo.Codigo_Grupo;
                    nodo1.id = grupo.Id_Grupo;
                    nodoGrupo.Tag = nodo1;
                    nodoClase.Nodes.Add(nodoGrupo);
                    List<SicCuenta> cuentas = this.db.ObtenerCuentas(grupo.Id_Grupo);
                    foreach (SicCuenta cuenta in cuentas)
                    {
                        TreeNode nodoCuenta = new TreeNode(cuenta.Codigo_Cuenta + " - " + cuenta.Nombre_Cuenta);
                        Nodo nodo2 = new Nodo();
                        nodo2.nombre = cuenta.Nombre_Cuenta;
                        nodo2.codigo = cuenta.Codigo_Cuenta;
                        nodo2.id = cuenta.Id_Cuenta;
                        nodoCuenta.Tag = nodo2;
                        nodoGrupo.Nodes.Add(nodoCuenta);
                        List<SicCuenta> cuentasP = this.db.ObtenerCuentas(cuenta.Id_Cuenta.ToString());
                        foreach (SicCuenta cuentaP in cuentasP)
                        {
                            TreeNode nodoCuentaP = new TreeNode(cuentaP.Codigo_Cuenta + " - " + cuentaP.Nombre_Cuenta);
                            Nodo nodo3 = new Nodo();
                            nodo3.nombre = cuentaP.Nombre_Cuenta;
                            nodo3.codigo = cuentaP.Codigo_Cuenta;
                            nodo3.id = cuentaP.Id_Cuenta;
                            nodoCuentaP.Tag = nodo3;
                            nodoCuenta.Nodes.Add(nodoCuentaP);
                            List<SicCuenta> cuentasS = this.db.ObtenerCuentas(cuentaP.Id_Cuenta.ToString());
                            foreach (SicCuenta cuentaS in cuentasS)
                            {
                                TreeNode nodoCuentaS = new TreeNode(cuentaS.Codigo_Cuenta + " - " + cuentaS.Nombre_Cuenta);
                                Nodo nodo4 = new Nodo();
                                nodo4.nombre = cuentaS.Nombre_Cuenta;
                                nodo4.codigo = cuentaS.Codigo_Cuenta;
                                nodo4.id = cuentaS.Id_Cuenta;
                                nodoCuentaS.Tag = nodo4;
                                nodoCuentaP.Nodes.Add(nodoCuentaS);
                            }
                        }
                    }
                }
            }
            this.treeCatalogo.ExpandAll();
        }

        private void btnAgregarClase_Click(object sender, EventArgs e)
        {
            try
            {
                int idClase = this.db.ObtenerMaxIdClase();
                SicClase clase = new SicClase();
                clase.Id_Clase = ++idClase;
                clase.Nombre_Clase = this.txtAgregarNombreClase.Text;
                clase.Estado = 1;
                this.db.SicClase.InsertOnSubmit(clase);
                this.db.SubmitChanges();
                MessageBox.Show("La clase se AGREGÓ éxitosamente", "Agregar Clase", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message + "\n\nPila de llamadas: " + ex.StackTrace, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                this.txtAgregarNombreClase.Text = "";
                this.llenarArbol();
                this.treeCatalogo.Nodes[0].EnsureVisible();
            }
        }

        private void treeCatalogo_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode nodo = this.treeCatalogo.SelectedNode;
            Nodo n = (Nodo)nodo.Tag;
            this.grupoPanelAgregarSubcuenta.Visible = (nodo.Level != 4);
            this.btnEliminarCuenta.Enabled = !(n.codigo.ToString().Equals("1") || n.codigo.ToString().Equals("2") || n.codigo.ToString().Equals("3") || n.codigo.ToString().Equals("4") || n.codigo.ToString().Equals("5"));
            this.btnModificarCuenta.Enabled = !(n.codigo.ToString().Equals("1") || n.codigo.ToString().Equals("2") || n.codigo.ToString().Equals("3") || n.codigo.ToString().Equals("4") || n.codigo.ToString().Equals("5"));

            this.panelLateralCuentas.IsOpen = true;
            this.labelCodigoCuenta.Text = n.codigo.ToString();
            this.txtNombreCuenta.Text = n.nombre;
            this.hiddenIdCuenta.Text = n.id.ToString();
            this.hiddenLevelNodo.Text = nodo.Level.ToString();
            this.hiddenNombreCuenta.Text = n.nombre;
            this.hiddenCaso.Text = (n.codigo.ToString().Length == 2) ? "1" : "0";
        }

        private void btnModificarCuenta_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.hiddenLevelNodo.Text.Equals("0"))
                    (from c in this.db.SicClase
                     where c.Id_Clase == Convert.ToInt32(this.labelCodigoCuenta.Text)
                     select c).SingleOrDefault().Nombre_Clase = this.txtNombreCuenta.Text;
                else if (this.hiddenLevelNodo.Text.Equals("1"))
                    (from c in this.db.SicGrupo
                     where c.Codigo_Grupo == Convert.ToInt32(this.labelCodigoCuenta.Text)
                     select c).SingleOrDefault().Nombre_Grupo = this.txtNombreCuenta.Text;
                else
                    (from c in this.db.SicCuenta
                     where c.Codigo_Cuenta == Convert.ToInt32(this.labelCodigoCuenta.Text)
                     select c).SingleOrDefault().Nombre_Cuenta = this.txtNombreCuenta.Text;

                this.db.SubmitChanges();
                MessageBox.Show("La cuenta fue modificada éxitosamente", "Modificar Cuenta", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message + "\n\nPila de llamadas: " + ex.StackTrace, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                this.llenarArbol();
                this.treeCatalogo.Nodes[0].EnsureVisible();
                this.panelLateralCuentas.IsOpen = false;
            }
        }

        private void btnEliminarCuenta_Click(object sender, EventArgs e)
        {
            try
            {
                DialogResult dr = MessageBox.Show("¿Está seguro que desea eliminar la cuenta '" + this.hiddenNombreCuenta.Text + "'?\n" +
                    "Si esta cuenta tiene subcuentas, también serán eliminadas.", "Eliminar Cuenta", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                if (dr == DialogResult.Yes)
                {
                    if (this.hiddenLevelNodo.Text.Equals("0"))
                        (from c in this.db.SicClase
                         where c.Id_Clase == Convert.ToInt32(this.labelCodigoCuenta.Text)
                         select c).SingleOrDefault().Estado = 0;
                    else if (this.hiddenLevelNodo.Text.Equals("1"))
                        (from c in this.db.SicGrupo
                         where c.Codigo_Grupo == Convert.ToInt32(this.labelCodigoCuenta.Text)
                         select c).SingleOrDefault().Estado = 0;
                    else
                        (from c in this.db.SicCuenta
                         where c.Codigo_Cuenta == Convert.ToInt32(this.labelCodigoCuenta.Text)
                         select c).SingleOrDefault().Estado = 0;
                    this.db.SubmitChanges();
                    MessageBox.Show("La cuenta fue eliminada éxitosamente", "Eliminar Cuenta", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.llenarArbol();
                    this.treeCatalogo.Nodes[0].EnsureVisible();
                    this.panelLateralCuentas.IsOpen = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message + "\n\nPila de llamadas: " + ex.StackTrace, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnAgregarCuenta_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.hiddenLevelNodo.Text.Equals("0"))
                {
                    int codigo = this.db.ObtenerMaxCodigoSicGrupo(Int32.Parse(this.hiddenIdCuenta.Text));
                    SicGrupo grupo = new SicGrupo();
                    grupo.Nombre_Grupo = this.txtNombreAgregarCuenta.Text;
                    grupo.Codigo_Grupo = Convert.ToByte(++codigo);
                    grupo.SicClase_Id_Clase = Convert.ToInt32(this.hiddenIdCuenta.Text);
                    grupo.Estado = 1;
                    this.db.SicGrupo.InsertOnSubmit(grupo);
                }
                else
                {
                    int codigo = this.db.ObtenerMaxCodigoSicCuenta(Int32.Parse(this.hiddenIdCuenta.Text), Int32.Parse(this.hiddenCaso.Text));
                    int idGrupo = (this.hiddenLevelNodo.Text == "1") ? this.db.ObtenerIdGrupo(this.labelCodigoCuenta.Text) : this.db.ObtenerIdGrupo(codigo.ToString().Substring(0, 2));
                    SicCuenta cuentaObj = new SicCuenta();
                    cuentaObj.Codigo_Cuenta = ++codigo;
                    cuentaObj.Nombre_Cuenta = this.txtNombreAgregarCuenta.Text;
                    cuentaObj.SicGrupo_Id_Grupo = idGrupo;
                    cuentaObj.Estado = 1;
                    if (this.hiddenCaso.Text == "1")
                        cuentaObj.SicCuenta_Id_Cuenta = null;
                    else
                        cuentaObj.SicCuenta_Id_Cuenta = Int32.Parse(this.hiddenIdCuenta.Text);
                    this.db.SicCuenta.InsertOnSubmit(cuentaObj);
                }
                this.db.SubmitChanges();
                MessageBox.Show("La subcuenta fue agregada éxitosamente", "Agregar Subcuenta", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message + "\n\nPila de llamadas: " + ex.StackTrace, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                this.panelLateralCuentas.IsOpen = false;
                this.txtNombreAgregarCuenta.Text = "";
                this.llenarArbol();
                this.treeCatalogo.Nodes[0].EnsureVisible();
            }
        }

        #endregion

        #region Otras Transacciones

        private AutoCompleteStringCollection autoCompleteCuentas()
        {
            AutoCompleteStringCollection coleccion = new AutoCompleteStringCollection();
            //recorrer y cargar los items para el autocompletado
            List<SicCuenta> lista = this.db.ObtenerCuentasNodo();
            foreach (SicCuenta cuenta in lista)
                coleccion.Add(cuenta.Codigo_Cuenta.ToString());
            return coleccion;
        }

        private void txtCodigoCuentaOtrasTransacciones_TextChanged(object sender, EventArgs e)
        {
            if (!this.txtCodigoCuentaOtrasTransacciones.Text.Equals(""))
            {
                SicCuenta cuenta = this.db.ObtenerCuentasNodo(this.txtCodigoCuentaOtrasTransacciones.Text);
                if (cuenta != null)
                    this.labelNombreCuentaOtrasTransacciones.Text = cuenta.Nombre_Cuenta;
                else
                    this.labelNombreCuentaOtrasTransacciones.Text = "";
            }
            else
                this.labelNombreCuentaOtrasTransacciones.Text = "";
            this.btnAgregarCuentaOtrasTransacciones.Enabled = !this.labelNombreCuentaOtrasTransacciones.Text.Equals("");
        }

        private void txtCargoOtrasTransacciones_KeyUp(object sender, KeyEventArgs e)
        {
            this.txtAbonoOtrasTransacciones.Enabled = this.txtCargoOtrasTransacciones.Text.Equals("");
        }

        private void txtAbonoOtrasTransacciones_KeyUp(object sender, KeyEventArgs e)
        {
            this.txtCargoOtrasTransacciones.Enabled = this.txtAbonoOtrasTransacciones.Text.Equals("");
        }

        private void btnAgregarCuentaOtrasTransacciones_Click(object sender, EventArgs e)
        {
            if (this.txtAbonoOtrasTransacciones.ValueObject == null && this.txtCargoOtrasTransacciones.ValueObject == null)
            {
                MessageBox.Show("Debe CARGAR o ABONAR la cuenta que desea agregar.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            Double cargo = Double.Parse(this.txtCargoOtrasTransacciones.Value.ToString());
            Double abono = Double.Parse(this.txtAbonoOtrasTransacciones.Value.ToString());
            this.tablaCuentasOtrasTransacciones.Rows.Add(this.txtCodigoCuentaOtrasTransacciones.Text, String.Format("{0:#,0.00}", cargo),
                String.Format("{0:#,0.00}", abono));
            this.txtAbonoOtrasTransacciones.Text = "";
            this.txtCargoOtrasTransacciones.Text = "";
            this.txtCodigoCuentaOtrasTransacciones.Text = "";
            this.labelNombreCuentaOtrasTransacciones.Text = "";
            this.txtAbonoOtrasTransacciones.Enabled = true;
            this.txtCargoOtrasTransacciones.Enabled = true;
        }

        private void tablaCuentasOtrasTransacciones_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
        {
            this.btnGuardarTransaccion.Enabled = true;
            Double monto;
            if (this.existePartidaDoble(out monto))
                this.txtImporteOtrasTransacciones.Text = String.Format("{0:#,0.00}", monto);
            else
                this.txtImporteOtrasTransacciones.Text = "";
        }

        private void tablaCuentasOtrasTransacciones_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
        {
            if (this.tablaCuentasOtrasTransacciones.RowCount == 0)
            {
                this.btnGuardarTransaccion.Enabled = false;
                this.txtImporteOtrasTransacciones.Text = "";
            }
            else
            {
                Double monto;
                if (this.existePartidaDoble(out monto))
                    this.txtImporteOtrasTransacciones.Text = String.Format("{0:#,0.00}", monto);
                else
                    this.txtImporteOtrasTransacciones.Text = "";
            }
        }

        private void eliminarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (this.tablaCuentasOtrasTransacciones.RowCount > 0)
            {
                this.tablaCuentasOtrasTransacciones.Rows.Remove(this.tablaCuentasOtrasTransacciones.CurrentRow);
            }
        }

        private bool existePartidaDoble(out Double saldo)
        {
            Double saldoDeudor = 0.0, saldoAcreedor = 0.0;
            DataGridViewRowCollection filas = this.tablaCuentasOtrasTransacciones.Rows;
            foreach (DataGridViewRow fila in filas)
            {
                saldoDeudor += (Double.Parse(fila.Cells[1].Value.ToString()) );
                saldoAcreedor += (Double.Parse(fila.Cells[2].Value.ToString()) );
            }
            saldo = saldoAcreedor;
            return (saldoAcreedor == saldoDeudor);
        }

        private bool fechaValida(bool ajuste, DateTime fecha)
        {
            if (ajuste)
            {
                if ((fecha.CompareTo(this.periodoContable.Fecha_Inicio.Value) >= 0 && fecha.CompareTo(this.periodoContable.Fecha_Fin.Value) <= 0) || (fecha.CompareTo(this.periodoContable.Fecha_Inicio.Value) < 0))
                    return false;
            }
            else
                if (fecha.CompareTo(this.periodoContable.Fecha_Inicio.Value) < 0)
                    return false;
            return true;
        }

        private void btnGuardarTransaccion_Click(object sender, EventArgs e)
        {
            Double monto;
            if (this.existePartidaDoble(out monto))
            {
                if (this.controlesNullos(this.txtFechaOtrasTransacciones.ValueObject == null, this.txtConceptoOtrasTransacciones.Text.Equals("")))
                    return;
                if (this.tablaCuentasOtrasTransacciones.RowCount <= 1)
                {
                    MessageBox.Show("Debe agregar al menos 2 cuentas para realizar la transacción.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (this.periodoContable.Estado == 0 && !this.fechaValida(this.periodoContable.Estado == 0, this.txtFechaOtrasTransacciones.Value))
                {
                    MessageBox.Show("La FECHA ingresada no puede ser antigua o estar dentro del Período Contable." +
                    "\n\nEl Período Contable es del " + this.periodoContable.Fecha_Inicio.Value.ToShortDateString() + " al " +
                    this.periodoContable.Fecha_Fin.Value.ToShortDateString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                if (!this.fechaValida(false, this.txtFechaOtrasTransacciones.Value))
                {
                    MessageBox.Show("La FECHA ingresada no puede ser antigua a la fecha de inicio del Período Contable." + 
                    "\n\nLa fecha de inicio es: " + this.periodoContable.Fecha_Inicio.Value.ToShortDateString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                try
                {
                    int idTransaccion = this.db.ObtenerMaxIdTransaccion();
                    this.db.SicTransaccion.InsertOnSubmit(
                        new SicTransaccion() { Id_Transaccion = ++idTransaccion, 
                            Concepto_Transaccion = this.txtConceptoOtrasTransacciones.Text,
                            Fecha_Transaccion = this.txtFechaOtrasTransacciones.Value,
                            Importe_Transaccion = Convert.ToDecimal(monto),
                            Ajuste_Transaccion = Convert.ToByte(this.periodoContable.Estado == 0),
                            SicPeriodo_Id_Periodo = this.periodoContable.Id_Periodo
                        });
    
                    DataGridViewRowCollection filas = this.tablaCuentasOtrasTransacciones.Rows;
                    foreach (DataGridViewRow fila in filas)
                    {
                        SicCuenta sicCuenta = this.db.ObtenerCuenta(fila.Cells[0].Value.ToString());

                        this.db.SicPartida.InsertOnSubmit(new SicPartida() { 
                            SicTransaccion_Id_Transaccion = idTransaccion,
                            SicCuenta_Id_Cuenta = sicCuenta.Id_Cuenta,
                            Cargo_Partida = Decimal.Parse(fila.Cells[1].Value.ToString()),
                            Abono_Partida = Decimal.Parse(fila.Cells[2].Value.ToString()),
                        });
                        Decimal nuevoSaldoDeudor = sicCuenta.Saldo_Deudor + Decimal.Parse(fila.Cells[1].Value.ToString());
                        Decimal nuevoSaldoAcreedor = sicCuenta.Saldo_Acreedor + Decimal.Parse(fila.Cells[2].Value.ToString());
                        SicCuenta cuenta = (from c in this.db.SicCuenta
                                            where c.Id_Cuenta == sicCuenta.Id_Cuenta
                                            select c).SingleOrDefault();
                        cuenta.Saldo_Deudor = nuevoSaldoDeudor;
                        cuenta.Saldo_Acreedor = nuevoSaldoAcreedor;
                    }
                    this.autoSumarCuentasSuperiores();
                    this.db.SubmitChanges();
                    MessageBox.Show("La transacción cumplió Partida Doble, por lo tanto se registró satisfactoriamente.", "Transacción Realizada", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.btnOtrasTransacciones_Click(null, null);
                    this.txtFechaOtrasTransacciones.Select();
                }
                catch (Exception ex)
                {
                    mensajeError(ex);
                }
            }
            else
                MessageBox.Show("El DEBE y HABER no cuadran. No se está cumpliendo Partida Doble.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        #endregion 

        #region Compras

        private void eliminarToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (this.tablaCompras.RowCount > 0)
            {
                this.tablaCompras.Rows.Remove(this.tablaCompras.CurrentRow);
                this.autoSumarTotalCompras();
            }
        }

        private void autoSumarTotalCompras()
        {
            var collection = this.tablaCompras.Rows;
            Decimal saldo = 0;
            foreach (DataGridViewRow item in collection)
                saldo += Convert.ToDecimal(item.Cells[5].Value);
            this.txtMontoCompras.Text = saldo.ToString("#,0.00");
        }
        
        private void btnAgregarProductoCompra_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.txtFechaCompras.ValueObject == null, this.txtCantidadProductoCompra.ValueObject == null, this.txtPrecioCompra.ValueObject == null))
                return;
            SicProducto producto = (SicProducto)this.cmbProductoCompra.SelectedItem;
            
            ComboItem tipo = (ComboItem)this.cmbTipoCompra.SelectedItem;
            this.tablaCompras.Rows.Add(this.txtFechaCompras.Value.ToShortDateString(), producto.Nombre_Producto, tipo.Text, this.txtCantidadProductoCompra.Value.ToString(),
                this.txtPrecioCompra.Value.ToString("#,0.00"), (this.txtPrecioCompra.Value * this.txtCantidadProductoCompra.Value).ToString("#,0.00"),
                producto.Id_Producto, tipo.Value, (this.txtPrecioCompra.Value * this.txtCantidadProductoCompra.Value * 1.13).ToString("#,0.00"));
            this.txtCantidadProductoCompra.ValueObject = null;
            this.txtPrecioCompra.ValueObject = null;
            this.cmbProductoCompra.SelectedIndex = 0;
            this.cmbTipoCompra.SelectedIndex = 0;
            this.autoSumarTotalCompras();
        }

        private void btnAceptarCompra_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.controlesNullos(this.tablaCompras.RowCount == 0))
                    return;
                var collection = this.tablaCompras.Rows;
                foreach (DataGridViewRow item in collection)
                {
                    SicKardex kardex = new SicKardex();
                    DateTimeInput fecha = new DateTimeInput();
                    fecha.ValueObject = item.Cells[0].Value;
                    kardex.Fecha = fecha.Value;
                    kardex.SicProducto = this.db.SicProducto.Single(c => c.Id_Producto == Convert.ToInt32(item.Cells[6].Value));
                    kardex.Tipo_Registro = Convert.ToByte(item.Cells[7].Value);
                    kardex.Cantidad = Convert.ToInt32(item.Cells[3].Value);
                    kardex.Costo_Unitario = Convert.ToDecimal(item.Cells[4].Value);
                    kardex.Tipo_Transaccion = 1; //Entrada Materia prima
                    kardex.Existencia += kardex.Cantidad;
                    kardex.SicPeriodo = this.periodoContable;
                    this.db.SicKardex.InsertOnSubmit(kardex);
                }
                this.db.SubmitChanges();
                MessageBox.Show("La compra se realizó con éxito.", "Compra Realizada", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
            finally
            {
                this.btnCompras_Click(null, null);
            }
        }

        #endregion

        #region Ventas

        private void cmbProductoVentas_SelectedValueChanged(object sender, EventArgs e)
        {
            
        }

        private void autoSumarTotalVentas()
        {
            var collection = this.tablaVentas.Rows;
            Decimal saldo = 0;
            foreach (DataGridViewRow item in collection)
                saldo += Convert.ToDecimal(item.Cells[5].Value);
            this.txtMontoTotalVentas.Text = saldo.ToString("#,0.00");
        }

        private void eliminarToolStripMenuItem2_Click(object sender, EventArgs e)
        {
            if (this.tablaVentas.RowCount > 0)
            {
                this.tablaVentas.Rows.Remove(this.tablaVentas.CurrentRow);
                this.autoSumarTotalVentas();
            }
        }

        private void btnAgregarProductosVentas_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.txtFechaVentas.ValueObject == null, this.txtCantidadVentas.ValueObject == null, this.txtPrecioVenta.ValueObject == null))
                return;
            SicProducto producto = (SicProducto)this.cmbProductoVentas.SelectedItem;
            if (this.existenciaProducto(producto) < this.txtCantidadVentas.Value)
            {
                MessageBox.Show("Ingrese una cantidad menor o igual a la existencia del producto.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            ComboItem tipo = (ComboItem)this.cmbTipoVentas.SelectedItem;
            //Método de Valoración de Inventario PEPS
            var collection = this.valoracionInventario(this.txtCantidadRequisiciones.Value, producto);

            foreach (var item in collection)
                this.tablaVentas.Rows.Add(this.txtFechaVentas.Value.ToShortDateString(), producto.Nombre_Producto, tipo.Text, this.txtCantidadVentas.Value.ToString(),
                item.CostoUnitario.ToString("#,0.00"), this.txtPrecioVenta.Value.ToString("#,0.00"), (this.txtPrecioVenta.Value * this.txtCantidadVentas.Value).ToString("#,0.00"),
                producto.Id_Producto, tipo.Value, (this.txtPrecioVenta.Value * this.txtCantidadVentas.Value * 1.13).ToString("#,0.00"));

            this.labelEnExistenciaRequisiciones.Text = this.existenciaProducto(producto).ToString() + " kg";
                        
            this.txtCantidadVentas.ValueObject = null;
            this.txtPrecioVenta.ValueObject = null;
            if (this.cmbProductoVentas.Items.Count > 0)
                this.cmbProductoVentas.SelectedIndex = 0;
            if (this.cmbTipoVentas.Items.Count > 0)
                this.cmbTipoVentas.SelectedIndex = 0;
            this.txtMontoTotalVentas.Text = "";
            this.autoSumarTotalVentas();
        }

        private void btnAceptarVenta_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.controlesNullos(this.tablaVentas.RowCount == 0))
                    return;
                
                var collection = this.tablaVentas.Rows;
                foreach (DataGridViewRow item in collection)
                {
                    SicKardex kardex = new SicKardex();
                    DateTimeInput fecha = new DateTimeInput();
                    fecha.ValueObject = item.Cells[0].Value;
                    kardex.Fecha = fecha.Value;
                    kardex.SicProducto = this.db.SicProducto.Single(c => c.Id_Producto == Convert.ToInt32(item.Cells[7].Value));
                    kardex.Tipo_Registro = Convert.ToByte(item.Cells[8].Value);
                    kardex.Cantidad = Convert.ToInt32(item.Cells[3].Value);
                    kardex.Costo_Unitario = Convert.ToDecimal(item.Cells[4].Value);
                    kardex.Costo_Adicional = Convert.ToDecimal(item.Cells[5].Value);
                    kardex.Tipo_Transaccion = 2; //Salida de Producto Terminado
                    kardex.Existencia += kardex.Cantidad;
                    kardex.SicPeriodo = this.periodoContable;
                    this.db.SicKardex.InsertOnSubmit(kardex);
                }
                this.db.SubmitChanges();
                MessageBox.Show("La venta se realizó con éxito.", "Venta Realizada", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
            finally
            {
                this.btnVentas_Click(null, null);
            }
        }

        #endregion

        #region Requisiciones

        private List<Peps> valoracionInventario(long cantidad, SicProducto producto)
        {
            List<Peps> peps = new List<Peps>();
            var collection = this.db.SicKardex.Where(k => k.SicProducto_Id_Producto == producto.Id_Producto).OrderBy(o => o.Fecha).ToList();
            foreach (var item in collection)
            {
                if (item.Existencia == 0)
                    continue;
                Peps p = new Peps();

                if (cantidad > item.Existencia)
                {
                    p.Cantidad = item.Existencia;
                    p.CostoUnitario = item.Costo_Unitario;
                    cantidad -= item.Existencia;
                    item.Existencia = 0;
                    p.Existencia = 0;
                }
                else
                {
                    p.Cantidad = cantidad;
                    p.CostoUnitario = item.Costo_Unitario;
                    p.Existencia = item.Existencia - cantidad;
                    peps.Add(p);
                    item.Existencia = p.Existencia;
                    break;
                }
                peps.Add(p);
            }
            return peps;
        }

        private void salidaKardex(DateTime fecha, SicProducto producto, Peps peps)
        {
            SicKardex kardex = new SicKardex();
            kardex.Cantidad = Convert.ToInt32(peps.Cantidad);
            kardex.Costo_Unitario = peps.CostoUnitario;
            kardex.SicProducto = producto;
            kardex.SicPeriodo = this.periodoContable;
            kardex.Tipo_Transaccion = 2;
            kardex.Tipo_Registro = 1;
            kardex.Fecha = fecha;
            kardex.Existencia = peps.Existencia;
            this.db.SicKardex.InsertOnSubmit(kardex);
        }

        private long existenciaProducto(SicProducto producto)
        {
            long existencia = 0;
            var collection = this.db.SicKardex.Where(k => k.SicProducto_Id_Producto == producto.Id_Producto).ToList();
            foreach (var item in collection)
            {
                if (item.Tipo_Transaccion == 1) //Entrada
                    existencia += item.Existencia;
                
            }
            return existencia;
        }

        private void cmbDepartamentoSolicitanteRequisiciones_SelectionChangeCommitted(object sender, EventArgs e)
        {
            int idDepartamento = (Int32)this.cmbDepartamentoSolicitanteRequisiciones.SelectedValue;
            String departamento = (idDepartamento == 1) ? "Depto. Descamado y Eviscerado" : "Depto. Descabezado y Deshuesado";
            this.cmbProductoRequisiciones.DataSource = this.db.SicProducto.Where(p => p.SicTipoProducto_Id_Tipo_Producto == idDepartamento).ToList();
            this.cmbProductoRequisiciones.DisplayMember = "Nombre_Producto";
            this.cmbProductoRequisiciones.ValueMember = "Id_Producto";
            this.labelDepartamentoSolicitanteRequisiciones.Text = departamento;
            this.labelEnExistenciaRequisiciones.Text = this.existenciaProducto((SicProducto)this.cmbProductoRequisiciones.SelectedItem).ToString() + " kg";
        }

        private void cmbProductoRequisiciones_SelectionChangeCommitted(object sender, EventArgs e)
        {
            this.labelEnExistenciaRequisiciones.Text = this.existenciaProducto((SicProducto)this.cmbProductoRequisiciones.SelectedItem).ToString() + " kg";
        }

        private void btnAgregarProductoRequisicion_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.controlesNullos(this.txtFechaRequisiciones.ValueObject == null, this.txtCantidadRequisiciones.ValueObject == null))
                    return;
                SicProducto producto = (SicProducto)this.cmbProductoRequisiciones.SelectedItem;

                if (this.existenciaProducto(producto) < this.txtCantidadRequisiciones.Value)
                {
                    MessageBox.Show("Ingrese una cantidad menor o igual a la existencia del producto.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                //Método de Valoración de Inventario PEPS
                var collection = this.valoracionInventario(this.txtCantidadRequisiciones.Value, producto);

                //Efectuar salida del inventario del producto
                foreach (var item in collection)
                    this.salidaKardex(this.txtFechaRequisiciones.Value, producto, item);

                foreach (var item in collection)
                    this.tablaRequisicion.Rows.Add(this.txtFechaRequisiciones.Value.ToShortDateString(), producto.Nombre_Producto, item.Cantidad, "$ " + item.CostoUnitario.ToString("#,0.00"), "$ " + (item.Cantidad * item.CostoUnitario).ToString("#,0.00"));

                this.labelEnExistenciaRequisiciones.Text = this.existenciaProducto(producto).ToString() + " kg";
                
                this.txtCantidadRequisiciones.Value = 0;
                this.cmbDepartamentoSolicitanteRequisiciones.SelectedIndex = 0;
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnEnviarRequisicion_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.tablaRequisicion.RowCount == 0)
                {
                    MessageBox.Show("No hay requisiciones para enviar.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                this.db.SubmitChanges();
                MessageBox.Show("La requisición se envió satisfactoriamente.", "Requisición Enviada", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.btnRequisiciones_Click(null, null);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        #endregion

        #region Periodo Contable

        private void btnAceptarPeriodoContable_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.txtFechaInicioPeriodoContable.ValueObject != null)
                {
                    this.db.SicPeriodo.InsertOnSubmit(new SicPeriodo() { Fecha_Inicio = this.txtFechaInicioPeriodoContable.Value, Estado = 1 });
                    MessageBox.Show("El Periodo Contable ha sido iniciado.", "Inicio de Periodo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.panelIniciarPeriodoContable.IsOpen = false;
                    this.db.SubmitChanges();
                    this.periodoContable = this.db.ObtenerPeriodoContable();
                    this.comprobarPeriodoContable();
                    this.labelTituloOtrasTransacciones.Text = "Nueva Transacción";
                    this.panelHome.IsOpen = true;
                }
                else
                    MessageBox.Show("Debe escoger una fecha", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnAceptarCierrePeriodoContable_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.txtFechaCierrePeriodoContable.ValueObject != null)
                {
                    if (!this.fechaValida(false, this.txtFechaCierrePeriodoContable.Value))
                    {
                        MessageBox.Show("La FECHA ingresada no puede ser antigua a la fecha de inicio del Período Contable." +
                        "\n\nLa fecha de inicio es: " + this.periodoContable.Fecha_Inicio.Value.ToShortDateString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                    DialogResult dr = MessageBox.Show("¿Está seguro que desea CERRAR el Período Contable?", "Cierre de Periodo", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (dr == DialogResult.Yes)
                    {
                        SicPeriodo periodo = (from p in this.db.SicPeriodo
                         where p.Id_Periodo == this.periodoContable.Id_Periodo
                         select p).SingleOrDefault();
                        periodo.Fecha_Fin = this.txtFechaCierrePeriodoContable.Value;
                        periodo.Estado = 0;
                        this.db.SubmitChanges();
                        periodoContable.Fecha_Fin = this.txtFechaCierrePeriodoContable.Value;
                        MessageBox.Show("El Periodo Contable fue cerrado.\nEste abarcó del " + periodoContable.Fecha_Inicio.Value.ToShortDateString() + " al " + periodoContable.Fecha_Fin.Value.ToShortDateString() + ".", "Cierre de Periodo", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        this.panelCerrarPeriodoContable.IsOpen = false;
                        this.periodoContable = this.db.ObtenerPeriodoContable();
                        this.comprobarPeriodoContable();
                        this.porcentajeCapital.ShowDialog();
                        this.periodoContable.Porcentaje_Capital = this.porcentajeCapital.Valor;
                        this.db.SubmitChanges();
                        this.btnGenerarPlanilla_Click(null, null);
                    }
                }
                else
                    MessageBox.Show("Debe escoger una fecha", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        #endregion

        #region Gestión de Productos

        private void llenarTablaProductos()
        {
            this.tablaProductos.Rows.Clear();

            var productos = this.db.SicProducto.ToList();

            foreach (var item in productos)
                this.tablaProductos.Rows.Add(item.Id_Producto, item.Nombre_Producto, item.SicTipoProducto.Nombre_Tipo_Producto, item.SicCuenta.Nombre_Cuenta);

        }

        private void btnAgregarProducto_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.textoNombreProducto.Text.Equals(""), this.textCuentaAsociada.Text.Equals("")))
                return;
            try
            {
                SicProducto producto = new SicProducto();
                producto.Nombre_Producto = this.textoNombreProducto.Text;
                producto.SicCuenta_Id_Cuenta = this.db.ObtenerCuenta(this.textCuentaAsociada.Text).Id_Cuenta;
                producto.SicTipoProducto_Id_Tipo_Producto = Convert.ToInt32(this.comboBoxtipoProducto.SelectedValue);
                producto.Estado = 1;
                this.db.SicProducto.InsertOnSubmit(producto);
                this.db.SubmitChanges();
                MessageBox.Show("Se guardado con exito", "Agregar Producto", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.btnCatalogoDeProductos_Click(null, null);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnModificarProducto_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.textoNombreProductoMOD.Text.Equals(""), this.textoCuentaAsociadaMOD.Text.Equals("")))
                return;
            try
            {
                SicProducto producto = (from p in this.db.SicProducto
                                   where p.Id_Producto == Convert.ToInt32(this.textoIdentificadorMod.Text)
                                   select p).Cast<SicProducto>().SingleOrDefault();

                producto.Nombre_Producto = this.textoNombreProductoMOD.Text;
                producto.SicCuenta_Id_Cuenta = this.db.ObtenerCuenta(this.textoCuentaAsociadaMOD.Text).Id_Cuenta;
                producto.SicTipoProducto_Id_Tipo_Producto = Convert.ToInt32(this.comboBoxTipoProductoMOD.SelectedValue);
                this.db.SubmitChanges();
                MessageBox.Show("Se ha modificado con exito", "Agregar Producto", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.btnCatalogoDeProductos_Click(null, null);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnBorrarProducto_Click(object sender, EventArgs e)
        {
            try
            {
                SicProducto producto = (from p in this.db.SicProducto
                                        where p.Id_Producto == Convert.ToInt32(this.textoIdentificadorMod.Text)
                                        select p).Cast<SicProducto>().SingleOrDefault();
                producto.Estado = 0;
                this.db.SubmitChanges();
                MessageBox.Show("Se ha eliminado con éxito", "Eliminar Producto", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.btnCatalogoDeProductos_Click(null, null);
                if (this.tablaProductos.RowCount == 0)
                    this.panelModificarProducto.IsOpen = false;
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void tablaProductos_SelectionChanged(object sender, EventArgs e)
        {
            if (this.tablaProductos.CurrentRow != null)
            {
                this.textoIdentificadorMod.Text = this.tablaProductos.CurrentRow.Cells["identificador"].Value.ToString();
                this.textoNombreProductoMOD.Text = this.tablaProductos.CurrentRow.Cells["nombreDeProducto"].Value.ToString();
                this.comboBoxTipoProductoMOD.SelectedItem = this.db.SicTipoProducto.SingleOrDefault(p => p.Nombre_Tipo_Producto == this.tablaProductos.CurrentRow.Cells["tipoDeProducto"].Value.ToString());
                this.textoCuentaAsociadaMOD.Text = this.db.SicCuenta.SingleOrDefault(c => c.Nombre_Cuenta == this.tablaProductos.CurrentRow.Cells["cuentaAsociada"].Value.ToString()).Codigo_Cuenta.ToString();
            }
        }

        private void textCuentaAsociada_TextChanged(object sender, EventArgs e)
        {
            if (!this.textCuentaAsociada.Text.Equals(""))
            {
                SicCuenta cuenta = this.db.ObtenerCuentasNodo(this.textCuentaAsociada.Text);
                if (cuenta != null)
                    this.labelNombreCuentaAsociada.Text = cuenta.Nombre_Cuenta;
                else
                    this.labelNombreCuentaAsociada.Text = "";
            }
            else
                this.labelNombreCuentaAsociada.Text = "";
            this.btnAgregarProducto.Enabled = !this.labelNombreCuentaAsociada.Text.Equals("");
        }

        private void textoCuentaAsociadaMOD_TextChanged(object sender, EventArgs e)
        {
            if (!this.textoCuentaAsociadaMOD.Text.Equals(""))
            {
                SicCuenta cuenta = this.db.ObtenerCuentasNodo(this.textoCuentaAsociadaMOD.Text);
                if (cuenta != null)
                    this.labelNombreCuentaAsociadaMod.Text = cuenta.Nombre_Cuenta;
                else
                    this.labelNombreCuentaAsociadaMod.Text = "";
            }
            else
                this.labelNombreCuentaAsociadaMod.Text = "";
            this.btnModificarProducto.Enabled = !this.labelNombreCuentaAsociadaMod.Text.Equals("");
        }

        #endregion

        #region Gestión de Empleados

        private void llenarTablaEmpleados()
        {
            this.tablaEmpleados.Rows.Clear();
            var collection = this.db.SicEmpleado.ToList().Where(e => e.Estado == 1);
            foreach (var item in collection)
                this.tablaEmpleados.Rows.Add(item.Nombre_Completo, item.Id_Empleado, item.SicPuesto.Nombre_Puesto, item.Fecha_Contratacion.Value.ToShortDateString(), item.SicPuesto.Sueldo_Base.ToString("$ #,0.00"));
        }

        private void btnAgregarEmpleado_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.txtNombreEmpleado.Text.Equals(""), this.txtFechaContratacionEmpleado.ValueObject == null))
                return;
            try
            {
                SicEmpleado emp = new SicEmpleado();
                emp.Nombre_Completo = this.txtNombreEmpleado.Text;
                emp.SicPuesto = (SicPuesto)this.cmbPuestoEmpleado.SelectedItem;
                emp.Fecha_Contratacion = this.txtFechaContratacionEmpleado.Value;
                emp.Estado = 1;
                this.db.SicEmpleado.InsertOnSubmit(emp);
                this.db.SubmitChanges();
                MessageBox.Show("El empleado fue agregado éxitosamente.", "Empleado Agregado", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.llenarTablaEmpleados();
                this.txtNombreEmpleado.Text = "";
                this.cmbPuestoEmpleado.SelectedIndex = 0;
                this.txtFechaContratacionEmpleado.ValueObject = null;
            }
            catch (Exception ex)
            {
                mensajeError(ex);
                throw;
            }
        }

        private void btnModificarEmpleado_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.txtNombreEmpleadoMod.Text.Equals(""), this.txtFechaContratacionEmpleadoMod.ValueObject == null))
                return;
            try
            {
                SicEmpleado emp = this.db.SicEmpleado.SingleOrDefault(em => em.Id_Empleado == Convert.ToInt32(this.tablaEmpleados.CurrentRow.Cells[1].Value.ToString()));
                emp.Nombre_Completo = this.txtNombreEmpleadoMod.Text;
                emp.SicPuesto = (SicPuesto)this.cmbPuestoEmpleadoMod.SelectedItem;
                emp.Fecha_Contratacion = this.txtFechaContratacionEmpleadoMod.Value;
                this.db.SubmitChanges();
                MessageBox.Show("El empleado fue modificado éxitosamente", "Empleado Modificado", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.llenarTablaEmpleados();
            }
            catch (Exception ex)
            {
                mensajeError(ex);
                throw;
            }
        }

        private void btnEliminarEmpleado_Click(object sender, EventArgs e)
        {
            try
            {
                SicEmpleado emp = this.db.SicEmpleado.SingleOrDefault(em => em.Id_Empleado == Convert.ToInt32(this.tablaEmpleados.CurrentRow.Cells[1].Value.ToString()));
                emp.Estado = 0;
                this.db.SubmitChanges();
                MessageBox.Show("El empleado fue dado de baja éxitosamente", "Dar de baja", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.llenarTablaEmpleados();
            }
            catch (Exception ex)
            {
                mensajeError(ex);
                throw;
            }
        }

        private void tablaEmpleados_SelectionChanged(object sender, EventArgs e)
        {
            if (this.tablaEmpleados.CurrentRow != null)
            {
                this.txtNombreEmpleadoMod.Text = this.tablaEmpleados.CurrentRow.Cells["nombreEmpleado"].Value.ToString();
                this.labelNombreEmpleado.Text = this.tablaEmpleados.CurrentRow.Cells["nombreEmpleado"].Value.ToString();
                this.txtFechaContratacionEmpleadoMod.ValueObject = this.tablaEmpleados.CurrentRow.Cells["fechaContratacion"].Value;
                this.cmbPuestoEmpleadoMod.SelectedItem = this.db.SicPuesto.SingleOrDefault(p => p.Nombre_Puesto == this.tablaEmpleados.CurrentRow.Cells["puestoEmpleado"].Value.ToString());
            }
        }

        private void txtNombreEmpleadoMod_TextChanged(object sender, EventArgs e)
        {
            this.btnModificarEmpleado.Enabled = !this.txtNombreEmpleadoMod.Text.Equals("");
            this.btnEliminarEmpleado.Enabled = !this.txtNombreEmpleadoMod.Text.Equals("");
        }

        #endregion

        #region Gestión de Puestos y Salarios

        private void llenarTablaPuestos()
        {
            this.tablaPuestos.Rows.Clear();
            var collection = this.db.SicPuesto.ToList().Where(p => p.Estado == 1);
            foreach (var item in collection)
                this.tablaPuestos.Rows.Add(item.Nombre_Puesto, item.Id_Puesto, "$ " + item.Sueldo_Base.ToString("#,0.00"), "$ " + item.Valor_Hora_Extra.ToString("#,0.00"));
        }

        private void btnAgregarPuesto_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.txtSalarioPuesto.ValueObject == null, this.txtNombrePuesto.Text.Equals("")))
                return;
            try
            {
                SicPuesto puesto = new SicPuesto();
                puesto.Nombre_Puesto = this.txtNombrePuesto.Text;
                puesto.Sueldo_Base = Convert.ToDecimal(this.txtSalarioPuesto.Value);
                puesto.Valor_Hora_Extra = Convert.ToDecimal(this.txtValorHoraExtraPuesto.Value);
                this.db.SubmitChanges();
                MessageBox.Show("El puesto fue agregado éxitosamente.", "Puesto Agregado", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.txtSalarioPuesto.ValueObject = null;
                this.txtNombrePuesto.Text = "";
            }
            catch (Exception ex)
            {
                mensajeError(ex);
                throw;
            }
            finally
            {
                this.llenarTablaPuestos();
            }
        }

        private void btnModificarPuesto_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.txtSalarioPuestoMod.ValueObject == null, this.txtNombrePuestoMod.Text.Equals(""), this.txtValorHoraExtraPuestoMod.ValueObject == null))
                return;
            try
            {
                SicPuesto puesto = this.db.SicPuesto.SingleOrDefault(p => p.Id_Puesto == Convert.ToInt32(this.tablaPuestos.CurrentRow.Cells[1].Value));
                puesto.Nombre_Puesto = this.txtNombrePuestoMod.Text;
                puesto.Sueldo_Base = Convert.ToDecimal(this.txtSalarioPuestoMod.Value);
                puesto.Valor_Hora_Extra = Convert.ToDecimal(this.txtValorHoraExtraPuestoMod.Value);
                this.db.SubmitChanges();
                MessageBox.Show("El puesto fue modificado éxitosamente.", "Puesto Modificado", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
                throw;
            }
            finally
            {
                this.llenarTablaPuestos();
            }
        }

        private void btnEliminarPuesto_Click(object sender, EventArgs e)
        {
            try
            {
                SicPuesto puesto = this.db.SicPuesto.SingleOrDefault(p => p.Id_Puesto == Convert.ToInt32(this.tablaPuestos.CurrentRow.Cells[1].Value));
                puesto.Estado = 0;
                this.db.SubmitChanges();
                MessageBox.Show("El puesto fue eliminado éxitosamente.", "Puesto Eliminado", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
                throw;
            }
            finally
            {
                this.llenarTablaPuestos();
            }
        }

        private void tablaPuestos_SelectionChanged(object sender, EventArgs e)
        {
            if (this.tablaPuestos.CurrentRow != null)
            {
                SicPuesto puesto = this.db.SicPuesto.SingleOrDefault(p => p.Id_Puesto == Convert.ToInt32(this.tablaPuestos.CurrentRow.Cells[1].Value));
                this.txtNombrePuestoMod.Text = puesto.Nombre_Puesto;
                this.txtSalarioPuestoMod.ValueObject = puesto.Sueldo_Base;
                this.txtValorHoraExtraPuestoMod.ValueObject = puesto.Valor_Hora_Extra;
                this.labelNombrePuesto.Text = puesto.Nombre_Puesto;
            }
        }

        #endregion

        #region Generar Planilla

        private void llenarTablaGenerarPlanilla()
        {
            this.tablaGenerarPlanilla.Rows.Clear();
            var collection = this.db.SicEmpleado.ToList().Where(e => e.Estado == 1);
            foreach (var item in collection)
                this.tablaGenerarPlanilla.Rows.Add(item.Id_Empleado, item.Nombre_Completo);
        }

        private bool planillaExiste()
        {
            return this.db.SicPlanilla.ToList().Where(p => p.Fecha == this.periodoContable.Fecha_Fin.Value).Count() > 0;
        }

        private bool generarPlanilla()
        {
            try
            {
                if (this.planillaExiste())
                {
                    MessageBox.Show("Ya se generó anteriormente la planilla para este período contable.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
                List<SicPlanilla> listaPlanilla = new List<SicPlanilla>();
                var collection = this.tablaGenerarPlanilla.Rows;
                foreach (DataGridViewRow item in collection)
                {
                    SicPlanilla planilla = new SicPlanilla();
                    planilla.SicEmpleado = this.db.SicEmpleado.SingleOrDefault(e => e.Id_Empleado == Convert.ToInt32(item.Cells[0].Value));
                    planilla.Fecha = this.periodoContable.Fecha_Fin.Value;
                    planilla.Dias_Laborados = Convert.ToInt32(item.Cells[2].Value);
                    planilla.Horas_Extras = Convert.ToInt32(item.Cells[3].Value);
                    listaPlanilla.Add(planilla);
                }
                this.db.SicPlanilla.InsertAllOnSubmit(listaPlanilla);
                
                this.db.SubmitChanges();
                return true;
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
            return false;
        }

        private void btnAceptarGenerarPlanilla_Click(object sender, EventArgs e)
        {
            if (this.tablaGenerarPlanilla.RowCount > 0)
            {
                if (this.generarPlanilla())
                {
                    this.cmbMesPlanilla.SelectedValue = this.periodoContable.Fecha_Fin.Value.Month;
                    this.txtAñoPlanilla.Value = this.periodoContable.Fecha_Fin.Value.Year;
                    MessageBox.Show("La planilla se generó éxitosamente.", "Planilla Generada", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    String nombreMes = this.obtenerMeses().Where(m => m.numeroMes == this.periodoContable.Fecha_Fin.Value.Month).SingleOrDefault().nombreMes;
                    this.consultarPlanilla(this.periodoContable.Fecha_Fin.Value, nombreMes);
                }
            }
            else
                MessageBox.Show("No hay ningún empleado en el sistema.\nNo se puede generar la planilla.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        #endregion

        #region Consultar Planilla

        private void consultarPlanilla(DateTime fecha, String nombreMes)
        {
            this.bsPlanilla.Clear();
            var collection = this.db.ConsultarPlanilla(fecha, nombreMes);
            foreach (var item in collection)
                this.bsPlanilla.Add(item);
            this.reportPlanilla.RefreshReport();
            this.ocultarPanelesExcepto(this.panelPlanilla);
        }

        private void btnFiltroPlanilla_Click(object sender, EventArgs e)
        {
            Mes mes = (Mes)this.cmbMesPlanilla.SelectedItem;
            this.consultarPlanilla(new DateTime(this.txtAñoPlanilla.Value, Convert.ToInt32(this.cmbMesPlanilla.SelectedValue), 28), mes.nombreMes);
        }

        #endregion

        #region Estados Financieros

        private void generarBalanceComprobacion(DateTime fechaInicio, DateTime fechaFin)
        {
            this.bSBC.Clear();
            this.db.ActualizarCuentasEstadoFinanciero(fechaInicio, fechaFin);
            this.autoSumarCuentasSuperiores();
            List<BalanceComprobacion> balance = this.db.ObtenerBalanceComprobacion(fechaInicio.ToShortDateString(), fechaFin.ToShortDateString());
            foreach (BalanceComprobacion item in balance)
                this.bSBC.Add(item);
        }

        private Decimal generarEstadoResultado(DateTime fechaInicio, DateTime fechaFin)
        {
            this.bsERA.Clear();
            this.bsERD.Clear();
            this.db.ActualizarCuentasEstadoFinanciero(fechaInicio, fechaFin);
            this.autoSumarCuentasSuperiores();
            List<EstadoResultado> estadoResultadoA = this.db.ObtenerEstadoResultadoAcreedor(fechaInicio.ToShortDateString(), fechaFin.ToShortDateString());
            foreach (EstadoResultado item in estadoResultadoA)
                this.bsERA.Add(item);
            List<EstadoResultado> estadoResultadoD = this.db.ObtenerEstadoResultadoDeudor(fechaInicio.ToShortDateString(), fechaFin.ToShortDateString());
            foreach (EstadoResultado item in estadoResultadoD)
                this.bsERD.Add(item);
            var ingresos = (from a in estadoResultadoA
                            select a.saldoTotalIngresos).Last();
            var egresos = (from a in estadoResultadoD
                           select a.saldoTotalEgresos).Last();
            Decimal utilidades = Decimal.Add(Convert.ToDecimal(ingresos), Convert.ToDecimal(egresos));
            //Establecer la utilidad en la cuenta utilidad
            this.db.SicCuenta.Single(cu => cu.Codigo_Cuenta == 330101).Saldo_Acreedor = utilidades; //Cuenta Utilidad Del Ejercicio
            this.db.SicCuenta.Single(cu => cu.Codigo_Cuenta == 3301).Saldo_Acreedor = utilidades; //Cuenta Utilidades y Perdidas Del Ejercicio
            this.db.SubmitChanges();
            EstadoResultado er = new EstadoResultado();
            er.saldoTotalIngresos = "$ " + Convert.ToDecimal(ingresos).ToString("#,0.00;(#,0.00)");
            er.saldoTotalEgresos = "$ " + Convert.ToDecimal(egresos).ToString("#,0.00;(#,0.00)");
            er.utilidades = "$ " + utilidades.ToString("#,0.00;(#,0.00)");
            this.bsERD.Add(er);
            return utilidades;
        }

        private Decimal generarEstadoCapital(DateTime fechaInicio, DateTime fechaFin, int porcentaje)
        {
            this.bsECInversiones.Clear();
            this.bsECDesinversiones.Clear();
            this.bsECTotal.Clear();
            Decimal saldo = 0;
            ReportParameter parametro = new ReportParameter("reportParamPorcentaje", porcentaje + "%");
            this.reportEstadoCapital.LocalReport.SetParameters(parametro);
            List<EstadoCapital> collectionInversion = this.db.ObtenerEstadoCapitalInversion(fechaInicio.ToShortDateString(), fechaFin.ToShortDateString(), this.generarEstadoResultado(fechaInicio, fechaFin), porcentaje);
            foreach (var item in collectionInversion)
                this.bsECInversiones.Add(item);
            List<EstadoCapital> collectionDesinversion = this.db.ObtenerEstadoCapitalDesinversion(fechaInicio.ToShortDateString(), fechaFin.ToShortDateString());
            foreach (var item in collectionDesinversion)
                this.bsECDesinversiones.Add(item);
            
            //Obtener el total
            EstadoCapital estado = new EstadoCapital();
            EstadoCapital inversion = collectionInversion.First();
            if (collectionDesinversion.Count > 0)
            {
                EstadoCapital desinversion = collectionDesinversion.First();
                saldo = Decimal.Add(Convert.ToDecimal(inversion.saldoTotal.Substring(2)), Convert.ToDecimal(desinversion.saldoTotal.Substring(2)));
            }
            else 
            {
                String inver = inversion.saldoTotal.Substring(2).Replace("(", "-").Replace(")", "");
                saldo = Convert.ToDecimal(inver);
            } 

            estado.saldoTotal = "$ " + saldo.ToString("#,0.00;(#,0.00)");
            this.bsECTotal.Add(estado);
            return saldo;
        }

        private void generarBalanceGeneral(DateTime fechaInicio, DateTime fechaFin)
        {
            Decimal aportaciones = this.generarEstadoCapital(fechaInicio, fechaFin, this.periodoContable.Porcentaje_Capital);
            if (aportaciones > 0)
                this.db.SicCuenta.Single(c => c.Codigo_Cuenta == 3101).Saldo_Acreedor = aportaciones;
            else
                this.db.SicCuenta.Single(c => c.Codigo_Cuenta == 3101).Saldo_Deudor = aportaciones;
            this.bsBGActivos.Clear();
            this.bsBGPasivos.Clear();
            this.bsBGCapital.Clear();
            this.bsBGTotal.Clear();
            List<BalanceGeneral> collectionActivos = this.db.ObtenerBalanceGeneralActivos(fechaInicio.ToShortDateString(), fechaFin.ToShortDateString());
            foreach (var item in collectionActivos)
                this.bsBGActivos.Add(item);
            List<BalanceGeneral> collectionPasivos = this.db.ObtenerBalanceGeneralPasivos(fechaInicio.ToShortDateString(), fechaFin.ToShortDateString());
            foreach (var item in collectionPasivos)
                this.bsBGPasivos.Add(item);
            List<BalanceGeneral> collectionCapital = this.db.ObtenerBalanceGeneralCapital(fechaInicio.ToShortDateString(), fechaFin.ToShortDateString());
            foreach (var item in collectionCapital)
                this.bsBGCapital.Add(item);
            this.bsBGTotal.Add(this.db.ObtenerBalanceGeneralTotal());
        }

        private void btnFiltroBC_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.controlesNullos(this.txtFechaInicioBC.ValueObject == null, this.txtFechaFinBC.ValueObject == null))
                    return;
                this.generarBalanceComprobacion(this.txtFechaInicioBC.Value, this.txtFechaFinBC.Value);
                this.reportBalanceComprobacion.RefreshReport();
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnFiltroER_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.controlesNullos(this.txtFechaInicioER.ValueObject == null, this.txtFechaFinER.ValueObject == null))
                    return;
                this.generarEstadoResultado(this.txtFechaInicioER.Value, this.txtFechaFinER.Value);
                this.reportEstadoResultado.RefreshReport();
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnFiltroEC_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.controlesNullos(this.txtFechaInicioEC.ValueObject == null, this.txtFechaFinEC.ValueObject == null))
                    return;
                this.generarEstadoCapital(this.txtFechaInicioEC.Value, this.txtFechaFinEC.Value, this.periodoContable.Porcentaje_Capital);
                this.reportEstadoCapital.RefreshReport();
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnFiltroBG_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.controlesNullos(this.txtFechaInicioBG.ValueObject == null, this.txtFechaFinBG.ValueObject == null))
                    return;
                this.generarBalanceGeneral(this.txtFechaInicioBG.Value, this.txtFechaFinBG.Value);
                this.reportBalanceGeneral.RefreshReport();
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnModificarPorcentajeEC_Click(object sender, EventArgs e)
        {
            this.porcentajeCapital.ShowDialog();
            this.periodoContable.Porcentaje_Capital = this.porcentajeCapital.Valor;
            this.db.SubmitChanges();
            this.btnEstadoCapital_Click(null, null);
        }

        #endregion        

        #region Usuarios

        public void llenarTablaUsuario()
        {
            this.tablaUsuarios.Rows.Clear();
            var usuarios = this.db.SicUsuario.ToList();

            foreach (var usuario in usuarios)
                this.tablaUsuarios.Rows.Add(usuario.Nombre_Usuario, usuario.Id_Usuario, usuario.Nick_Usuario, usuario.SicTipoUsuario.Nombre_Tipo_Usuario, usuario.SicTipoUsuario.Id_Tipo_Usuario);
        }

        private void btnAgregarUsuario_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.textContraseña.Text.Equals(""), this.textNombreUsuario.Text.Equals(""), this.textNickUsuario.Text.Equals("")))
                return;
            if (!this.textContraseña.Text.Equals(this.txtConfirmarContraseñaUsuario.Text))
            {
                MessageBox.Show("Las contraseñas no coinciden. Ingrese de nuevo.", "Error Contraseñas", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.textContraseña.Text = "";
                this.txtConfirmarContraseñaUsuario.Text = "";
                return;
            }
            try
            {                
                SicUsuario usuario = new SicUsuario();
                usuario.Nombre_Usuario = this.textNombreUsuario.Text;
                usuario.Nick_Usuario = this.textNickUsuario.Text;
                usuario.Contraseña = this.textContraseña.Text;
                usuario.SicTipoUsuario = (SicTipoUsuario)this.comboBoxTipoUsuario.SelectedItem;
                this.db.SicUsuario.InsertOnSubmit(usuario);
                this.db.SubmitChanges();
                
                MessageBox.Show("Se ha guardado con éxito el usuario","Usuario Agregado",MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.btnGestionarUsuarios_Click(null, null);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnModificarUsuario_Click(object sender, EventArgs e)
        {
            if (this.controlesNullos(this.textUsuarioContraseñaMOD.Text.Equals(""), this.textNombreUsuarioMOD.Text.Equals(""), this.textNickUsuarioMOD.Text.Equals("")))
                return;
            if (!this.textUsuarioContraseñaMOD.Text.Equals(this.txtConfirmarContraseñaUsuarioMOD.Text))
            {
                MessageBox.Show("Las contraseñas no coinciden. Ingrese de nuevo.", "Error Contraseñas", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.textUsuarioContraseñaMOD.Text = "";
                this.txtConfirmarContraseñaUsuarioMOD.Text = "";
                return;
            }
            try
            {
                SicUsuario usu = this.db.SicUsuario.SingleOrDefault(u => u.Id_Usuario == Convert.ToInt32(this.tablaUsuarios.CurrentRow.Cells[1].Value));
                usu.Nombre_Usuario = this.textNombreUsuarioMOD.Text;
                usu.Nick_Usuario = this.textNickUsuarioMOD.Text;
                usu.Contraseña = this.textUsuarioContraseñaMOD.Text;
                usu.SicTipoUsuario = (SicTipoUsuario)this.comboTipoUsuarioMOD.SelectedItem;
                this.db.SubmitChanges();//Guardando en base los datos modificacados
                MessageBox.Show("El usuario se modificó éxitosamente.", "Usuario Modificado", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.btnGestionarUsuarios_Click(null, null);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void btnEliminarUsuario_Click(object sender, EventArgs e)
        {
            try
            {
                SicUsuario usuario;
                usuario = this.db.SicUsuario.SingleOrDefault(usu => usu.Id_Usuario == Convert.ToInt32(this.tablaUsuarios.CurrentRow.Cells[1].Value));
                this.db.SicUsuario.DeleteOnSubmit(usuario);
                this.db.SubmitChanges();

                MessageBox.Show("Se he eliminado el usuario éxitosamente.", "Usuario Eliminado", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.btnGestionarUsuarios_Click(null, null);
            }
            catch (Exception ex)
            {
                mensajeError(ex);
            }
        }

        private void tablaUsuarios_SelectionChanged(object sender, EventArgs e)
        {
            if (this.tablaUsuarios.CurrentRow != null)
            {
                this.textNombreUsuarioMOD.Text = this.tablaUsuarios.CurrentRow.Cells[0].Value.ToString();
                this.textNickUsuarioMOD.Text = this.tablaUsuarios.CurrentRow.Cells[2].Value.ToString();
                SicUsuario usuario = this.db.SicUsuario.SingleOrDefault(s => s.Id_Usuario == Convert.ToInt32(this.tablaUsuarios.CurrentRow.Cells[1].Value));
                this.textUsuarioContraseñaMOD.Text = usuario.Contraseña;
                this.txtConfirmarContraseñaUsuarioMOD.Text = usuario.Contraseña;
                this.comboTipoUsuarioMOD.SelectedItem = this.db.SicTipoUsuario.SingleOrDefault(t => t.Id_Tipo_Usuario == Convert.ToInt32(this.tablaUsuarios.CurrentRow.Cells[4].Value));
            }
        }

        #endregion

    }

    public class Nodo
    {
        public String nombre { get; set; }
        public int codigo { get; set; }
        public int id { get; set; }
    }

    public class Mes
    {
        public int numeroMes { get; set; }
        public string nombreMes { get; set; }
    }

    public class Peps
    {
        public Int64 Cantidad { get; set; }
        public Decimal CostoUnitario { get; set; }
        public Int64 Existencia { get; set; }

    }

    public class Modulo
    {
        public int IdModulo { get; set; }
        public Object Mod { get; set; }
    }

}
